Win32 Global API Hook - 1 Win32 API ŷ ⺻
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(  Ī մϴ.)


ڽ      α׷Ӷ ̷  ѹ غ ̴.

" Windows API ŷ  ִٸ ִ   غ ٵ..."

׸ ǿ ð ־ٸ Ƹ غ   ־̴. ׷  ̰  
 ׸  ʾ ȴ.   ø̼  α׷ߴٸ ̰ Ұ
غ 𸥴. ý  α׷Ӷ ̰  ٷӰ ٷ  ° ˾
̴.  ⼭ ڴ   ñϴ  н ۾ ϳϳ Ǯ Ѵ. ׸
 ǿܷ   ش ־  °  ˰Ե ̴.

,    . 츮 Ϸ   .

Win32 API ŷؼ  ϴ ۾ ϰų, ۾ 帧 ϴ´   ִ.

 ̴̰.    ʿѰ?  츮 Ϸ  ̰ ̴.    
ڸ CreateProcess()  API ŷϸ  ʴ α׷   ְ, 
 send() recv() ŷϸ   Ŷ ĺų   ִ.    
°?  ʴ  Ƹ   ¸   ƴϰų Ŀ( ǹ) 
    ִ.

ϴ  ù̴ ׵   ߴ Windows API ŷ ؼ  غ.

1. exe  import descriptor table ϴ 

   ǰڴ.  ŭ   ʴ. ϴ Win32 α׷ PE(Portable 
Executable)̶  ̳ʸȭ Ǿִ. డ ̳ʸ ϱ POSIX, COFF, PE 
ĵ ִµ,  PE Ѵ.  PE ˸ ϱ м  ְ
.   ũ , ҽ, Ʈ̺, ͽƮ̺, , ڵ  
 µ ⼭ Ʈ̺ ̸ ״ Ʈ ̺귯 Լ   
.   ũ  Լ ̰  ְԵȴ. ׷ ̺κ Ʈ Լ ּ
   ŷԼּҷ ٲġָ  ̴. Ʒ Ʈ ڵ带 .

//  ȯ   ũ
#ifndef MakePtr
#define MakePtr(cast, ptr, addValue) (cast)((DWORD)(ptr)+(DWORD)(addValue))
#endif // MakePtr

PIMAGE_IMPORT_DESCRIPTOR GetImportDescriptor(HMODULE hMod,        // 
                                        
     LPCTSTR pszModName)// ̸
{
    TRACE("[FIND IMPORT DESCRIPTOR] \n");

    // Ű ȿ ˻
    ASSERT(!IsBadReadPtr(hMod, sizeof(IMAGE_DOS_HEADER)));
    ASSERT(NULL != pszModName);

    // DOS 
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
    if(IMAGE_DOS_SIGNATURE/*0x5A4D*/ == pDosHdr->e_magic)
    {
        // NT 
        PIMAGE_NT_HEADERS pNtHdr = MakePtr(PIMAGE_NT_HEADERS,
            pDosHdr, pDosHdr->e_lfanew);
        if(!IsBadReadPtr(pNtHdr, sizeof(IMAGE_NT_HEADERS))
            && IMAGE_NT_SIGNATURE/*0x00004550*/ == pNtHdr->Signature)
        {
            // image descriptor
            PIMAGE_IMPORT_DESCRIPTOR pImpDesc = 
                MakePtr(PIMAGE_IMPORT_DESCRIPTOR,
                    pDosHdr,
                    pNtHdr->OptionalHeader.
                    DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
                    VirtualAddress);
            if(NULL != pImpDesc)
            {
                while(NULL != pImpDesc->Name)
                {
                    PSTR pszName = MakePtr(PSTR, pDosHdr, (DWORD)pImpDesc-
>Name);
                    TRACE(" %s ", pszName);

                    if(stricmp(pszName, pszModName) == 0)
                    {
                        // ãҴ !!
                        TRACE(": Found It !! \n");

                        return pImpDesc;
                    }

                    TRACE("\n");
                    pImpDesc++;
                }
            }
        }
    }

    return NULL;
}

PROC WINAPI HookImportFunction(HMODULE hMod,// Hooking  
                     PSTR pszModName,        // Hooking Լ ġ ̸
                     PSTR pszFuncName,        // Hooking  Լ
                     PROC pfnNewProc)        // Hooking Լ
{
    // Ű ȿ ˻
    ASSERT(!IsBadReadPtr(hMod, sizeof(IMAGE_DOS_HEADER)));
    ASSERT(NULL != pszModName);
    ASSERT(NULL != pszFuncName);
    ASSERT(NULL != pfnNewProc);
    ASSERT(!IsBadCodePtr(pfnNewProc));

    // ȯ ( Լ)
    PROC pfnOrgProc = NULL;

    // Win9x̰ 2GB ̻ ý DLL ̶
    //   Ѵ.
    if(1 != __GetOsType() && 0x80000000 < (DWORD)hMod)
    {
        return NULL;
    }

    // import descriptor  ´.
    PIMAGE_IMPORT_DESCRIPTOR pImpDesc = GetImportDescriptor(hMod, pszModName);
    if(NULL == pImpDesc)
        return NULL;

    //  thunk
    PIMAGE_THUNK_DATA pOrgThunk = MakePtr(PIMAGE_THUNK_DATA,
        hMod, pImpDesc->OriginalFirstThunk);

    //  thunk (for Hooking)
    PIMAGE_THUNK_DATA pRealThunk = MakePtr(PIMAGE_THUNK_DATA,
        hMod, pImpDesc->FirstThunk);

    //  鼭 Hooking  Լ ã´.
    TRACE("[FIND IMPORT FUNCTION] : %s \n", pszModName);
    while(NULL != pOrgThunk->u1.Function)
    {
        // ̸ import Լ ˻
        if(IMAGE_ORDINAL_FLAG !=
            (pOrgThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG))
        {
            // import Լ ̸
            PIMAGE_IMPORT_BY_NAME pByName =
                MakePtr(PIMAGE_IMPORT_BY_NAME,
                hMod, pOrgThunk->u1.AddressOfData);

            // ̸ NULL ۵Ǹ Ѿ.
            if(0 == pByName->Name[0])
                continue;

            TRACE(" %s ", (PSTR)pByName->Name);

            if(pszFuncName[0] == pByName->Name[0]
                && 0 == stricmp(pszFuncName, (PSTR)pByName->Name))
            {
                // ãҴ !!
                TRACE(": Found It !! \n");

                MEMORY_BASIC_INFORMATION mbi;
                VirtualQuery(pRealThunk, &mbi, sizeof(mbi));

                //  ޸ ȣӼ 
                if(!VirtualProtect(mbi.BaseAddress, mbi.RegionSize,
                    PAGE_READWRITE, &mbi.Protect))
                {
                    // VirtualProtect() fail !!
                    ASSERT(0);
                    return NULL;
                }

                //  Լ(ȯ) 
                pfnOrgProc = (PROC)pRealThunk->u1.Function;

                // ο Լ .
                TRACE("** old function : 0x%08X \n", (DWORD)pRealThunk-
>u1.Function);
                pRealThunk->u1.Function =
                    (DWORD)pfnNewProc;
                TRACE("** new function : 0x%08X \n", (DWORD)pRealThunk-
>u1.Function);

                //  ޸ ȣӼ  ǵ
                DWORD dwTmp;
                VERIFY(VirtualProtect(mbi.BaseAddress, mbi.RegionSize,
                    mbi.Protect, &dwTmp));

                //    !!
                TRACE("** Hook OK !! What a wonderful world !! \n");
                return pfnOrgProc;
            }

            TRACE("\n");
        }

        pOrgThunk++;
        pRealThunk++;
    }

    return NULL;
}

GetImportDescriptor()Լ  Ʈũ͸  Լ̰, HookImportFunction()Լ 
 Ʈ Լ ũϴ Լ̴.   Լ ̿ؼ MessageBox API ŷغ.

// MessageBox API 
typedef int (WINAPI *PROC_MESSAGEBOX)(HWND, PSTR, PSTR, UINT);

PROC_MESSAGEBOX pfnOrgMessageBox = NULL;

// MessageBox ü Լ
int WINAPI MyMessageBoxA(HWND hWnd, PSTR pszText, PSTR pszTitle, UINT uType)
{
    ASSERT(NULL != pfnOrgMessageBox);

    return pfnOrgMessageBox(NULL, "Hooked MessageBox !!", "Hooked !!", MB_ICONINFORMATION);
}

// Main μ
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     // TODO: Place code here.

    MessageBox(NULL, "Default MessageBox", "Windows 98", MB_ICONINFORMATION);

    // hook !!
    pfnOrgMessageBox = (PROC_MESSAGEBOX)HookImportFunction(
        GetModuleHandle(NULL), "user32.dll", "MessageBoxA", (PROC)MyMessageBoxA);
    if(NULL == pfnOrgMessageBox)
        return 0;

    MessageBox(NULL, "Default MessageBox", "Windows 98", MB_ICONINFORMATION);

    // unhook !!
    pfnOrgMessageBox = (PROC_MESSAGEBOX)HookImportFunction(
        GetModuleHandle(NULL), "user32.dll", "MessageBoxA", (PROC)pfnOrgMessageBox);
    if(NULL == pfnOrgMessageBox)
        return 0;
    TRACE("replace orginal function \n");

    MessageBox(NULL, "Default MessageBox", "Windows 98", MB_ICONINFORMATION);

    return 0;
}

MyMessageBoxA  Լ  ŸƲ Hooked !!  ĸ  Hooked MessageBox !! ޽ 
ϴ ޽ ڽ ִ Լ̴. ŷ  ̷ MessageBox  Ͱ 
·  ɰ̴. MessageBoxA A ڴ ANSI ڿ μ Windows 9x 迭 ַ 
Ǹ 1Ʈ ڸ Ѵ. ݴ W  API Wide Charactorμ 2Ʈ ڸ ϴ 
ڵ  API̴.  Win9x 迭 Ұ A  API ȣǵ Ǿ 
, NT4/W2K 迭 δ W  API ȣȴ. ڿ ڷ ϴ κ 
API ̿Ͱ ΰ    Լ ġѴٸ Ȯ  ؾ Ұ̴.

Ѻ  ߰ MessageBox(NULL, "Default MessageBox", "Windows 98", 
MB_ICONINFORMATION); Լ 츮  ŷԼ üǾ Hooked ...  ޽ ڽ µɰ
̴.

,  ˰   Ǵ° Ȯߴٸ  ؼ ˾ƺ.
 δ   α׷ ŷɼ ִ. ｼ Ʈ ũ ̶̺° 
α׷  ִ°̱  翬  α׷ Ǿ. ׷ٸ ٸ α׷鵵 
 Ʈ ũ ̺ ϸ ɰ ƴѰ?  ϴ   𸣰, 
 Ұϴ. ֳϸ Win32 α׷   ּҰ Ǳ⶧ ⺻ 
 ٸ α׷  ħҼ . ׷  ٸ α׷(Ȯ ϸ μ)
 ּҰ ?   ؼ  ¿ ٷ  .

...
 Win32 API ŷ  ⿴.    δ 츮 ϴ ͵ ϱ⿡
 ξ ڶ. ׷   ֵ  ⺻ к غҴ.  
 ¿  μ   ϴ. ϴ Windows ϱ PE  
 Windows μ ޸   ſ ߿ ̴. (Ǵ ð ^^) ⼭  ٷ
  Ҹ  Ұϸ PE ؼ MSJ ũμƮ  ˻ϸ ã
  ̴.  PEDUMP  ƿƼ ۼغٸ  ̴. Win32 ޸𸮰 
ؼ Jeffry Richter Advanced Windows  å õѴ.   åε ڰ Ҷ 
 Ǹߴٰ  å̴. Ƹ ٸ ý α׷ ٷ å ڷḦ   
.   ҽڵ ü John Robbins Debugging Applications å ϴ ͵  
̴.

Ľɿ  ڸ, Ȥ C/C++ Windows ý۰ ī ͼ ʴٸ  ¸ 
° ϱ Ѵ.   ҽڵ    ־ Ұ̴.   
  Ͽ ι ¸ ø  . ׷ ü Ŀ   
 ʿ κ ̸̸ Ѵٸ    ̴.

1. Win32 API ŷ ⺻
2. ٸ μ ּҰ  !!
3. Win32  α׷
4. Win9x ̽ ̹(VxD) 
5.  α׷ - Shell Code ۼ
6. Win9x Global API Hooking
7. WinNT/2000 ̽ ̹ 
8. WinNT/2000 Global API Hooking

   ֿ ׸̴. ϳ    ̷ ѵȸ ·
 ξ   κ ̴. ׷  ٺ  ڽ Ƿ ½ 
Ǿ  Ǻη ̴. ̰ ڰ ̸ ɰ ͼ  ִ.  ̹̽ 
α׷ְ  α׷ֿ   ְų,  ϴ ŷ Stack Overflow
 ͽ÷հ ڵ带    ִ ɷ ִٸ ¸ Ⱑ Ѱ  ̴.

P.S :  ´ 󸶵 ٸ Ʈ Ǿ  ,  뵵 Ǿ , 
 Ǹ  մϴ. 縦 ϽǶ ǻ  ̸ ֽñ ٶϴ.